﻿using System;
using System.Collections.Generic;
using System.IO;
using System.IO.Compression;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Windows.ApplicationModel;
using Windows.Storage;
using Windows.Storage.Streams;

namespace mBook.Utils
{
    public class Utility
    {
        public static async Task UnZipFile(StorageFile epubFile)
        {
            using (var zipStream = await epubFile.OpenStreamForReadAsync())
            {
                StorageFolder folderEbook = await ApplicationData.Current.LocalFolder.CreateFolderAsync(Constants.FOLDER_DATA_EXTRACT, CreationCollisionOption.OpenIfExists);
                var destination = await folderEbook.CreateFolderAsync(epubFile.DisplayName, CreationCollisionOption.OpenIfExists);

                using (MemoryStream zipMemoryStream = new MemoryStream((int)zipStream.Length))
                {
                    await zipStream.CopyToAsync(zipMemoryStream);

                    using (var archive = new ZipArchive(zipMemoryStream, ZipArchiveMode.Read))
                    {
                        foreach (ZipArchiveEntry entry in archive.Entries)
                        {
                            await ExtractFile(destination, entry);

                            //await CreateRecursiveFolder(destination, entry);

                            //if (entry.Name == "")
                            //{
                            //    // Folder
                            //    await CreateRecursiveFolder(destination, entry);
                            //}
                            //else
                            //{
                            //    // File
                            //    await ExtractFile(destination, entry);
                            //}
                        }
                    }
                }
            }
        }

        private static async Task CreateRecursiveFolder(StorageFolder folder, ZipArchiveEntry entry)
        {
            StorageFolder folderEbook = await ApplicationData.Current.LocalFolder.CreateFolderAsync(Constants.FOLDER_DATA_EXTRACT, CreationCollisionOption.OpenIfExists);
            StorageFolder originFolder = await folderEbook.GetFolderAsync(folder.Name);

            var steps = entry.FullName.Split('/').ToList();

            steps.RemoveAt(steps.Count() - 1);

            foreach (var i in steps)
            {
                await folder.CreateFolderAsync(i, CreationCollisionOption.OpenIfExists);

                folder = await folder.GetFolderAsync(i);
            }
        }

        private static async Task ExtractFile(StorageFolder folder, ZipArchiveEntry entry)
        {
            bool isFile = false;
            if (entry.FullName.Contains("/"))
            {
                var steps = entry.FullName.Split('/').ToList();

                //steps.RemoveAt(steps.Count() - 1);

                foreach (var i in steps)
                {
                    if (i != "" && !i.Contains("."))
                        folder = await folder.CreateFolderAsync(i, CreationCollisionOption.OpenIfExists);
                    else if(i != "")
                        isFile = true;
                }
            }
            else
                isFile = true;

            if (isFile)
            {
                using (Stream fileData = entry.Open())
                {
                    StorageFile outputFile = await folder.CreateFileAsync(entry.Name, CreationCollisionOption.ReplaceExisting);

                    using (Stream outputFileStream = await outputFile.OpenStreamForWriteAsync())
                    {
                        await fileData.CopyToAsync(outputFileStream);
                        await outputFileStream.FlushAsync();
                    }
                }
            }
        }

        public static async Task<string> ConvertBase64(StorageFile imageFile)
        {
            var readStream = await imageFile.OpenAsync(FileAccessMode.Read);
            var inputStream = readStream.GetInputStreamAt(0);
            var dataReader = new DataReader(inputStream);

            var numBytesLoaded = await dataReader.LoadAsync((uint)readStream.Size);
            var byteString = new byte[numBytesLoaded];
            dataReader.ReadBytes(byteString);
            return Convert.ToBase64String(byteString);
        }
    }
}
